package com.beiding;

import com.beiding.hotel.Application;
import com.beiding.hotel.t.D;
import org.springframework.web.servlet.DispatcherServlet;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.net.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

public class B {
    public static void main(String[] args) throws Exception {

        start(82);
        start(83);

//        URL.setURLStreamHandlerFactory(listURLStreamHandlerFactory);

    }

    private static void start(int port) throws Exception {


        URLClassLoader classLoader = (URLClassLoader) ClassLoader.getSystemClassLoader();

        //TODO 将所有的类都进行重新加载并定义

        //可以自定义排除一些 url 进行局部重启
        RemoveAbleUrlClassLoader urlClassLoader = new RemoveAbleUrlClassLoader(classLoader.getURLs(), classLoader);

        //移除掉tomcat容器配置
        //urlClassLoader.remove("**/*tomcat*/**");

        Thread thread = new Thread(() -> {
            try {

                Thread.currentThread().setContextClassLoader(urlClassLoader);

                String name = Application.class.getName();

                Class<?> aClass = urlClassLoader.loadClass(name);

                Method main = aClass.getMethod("main", String[].class);

                main.invoke(null, (Object) new String[]{"--server.port=" + port});


            } catch (Exception e) {
                e.printStackTrace();
            }
        });

        thread.start();

        thread.join();

        Class<?> aClass = urlClassLoader.loadClass(D.class.getName());

        Method getDispatcherServlet = aClass.getMethod("getDispatcherServlet");

        //使用该Servlet 进行请求的分发
        DispatcherServlet dispatcherServlet = (DispatcherServlet) getDispatcherServlet.invoke(null);

        //handleUrl();
    }



    private static void handleUrl() throws Exception {
        Field factory = URL.class.getDeclaredField("factory");
        factory.setAccessible(true);
        URLStreamHandlerFactory o = (URLStreamHandlerFactory) factory.get(null);
        listURLStreamHandlerFactory.urlStreamHandlerFactories.add(o);
        factory.set(null, null);

    }

    private static ListURLStreamHandlerFactory listURLStreamHandlerFactory = new ListURLStreamHandlerFactory();

    private static class ListURLStreamHandlerFactory implements URLStreamHandlerFactory {

        private List<URLStreamHandlerFactory> urlStreamHandlerFactories = new ArrayList<>();

        @Override
        public URLStreamHandler createURLStreamHandler(String protocol) {

            for (URLStreamHandlerFactory urlStreamHandlerFactory : urlStreamHandlerFactories) {
                URLStreamHandler urlStreamHandler = urlStreamHandlerFactory.createURLStreamHandler(protocol);
                if (urlStreamHandler != null) {
                    return urlStreamHandler;
                }
            }

            return null;
        }
    }


}
